# -*- coding: utf-8 -*-
"""
配置管理模块

提供项目的配置管理功能，支持从文件、环境变量等多种方式加载配置
"""

import os
import json
from typing import Dict, Any, Optional
from pathlib import Path


class Config:
    """配置管理类"""
    
    def __init__(self, config_file: Optional[str] = None):
        self.config_file = config_file or os.path.join(os.path.dirname(__file__), '..', '..', 'config.json')
        self._config = self._load_default_config()
        self._load_config_file()
        self._load_env_config()
    
    def _load_default_config(self) -> Dict[str, Any]:
        """加载默认配置"""
        return {
            'output': {
                'base_dir': 'output',
                'charts_dir': 'charts',
                'reports_dir': 'reports',
                'data_dir': 'data'
            },
            'analysis': {
                'default_clusters': 3,
                'random_state': 42,
                'outlier_method': 'iqr',
                'outlier_threshold': 1.5,
                'missing_value_strategy': 'auto'
            },
            'visualization': {
                'figure_size': [10, 6],
                'dpi': 300,
                'style': 'whitegrid',
                'color_palette': 'viridis',
                'font_family': ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']
            },
            'clustering': {
                'algorithms': ['kmeans', 'hierarchical', 'dbscan', 'spectral'],
                'default_algorithm': 'kmeans',
                'evaluation_metrics': ['silhouette', 'calinski_harabasz', 'davies_bouldin']
            },
            'logging': {
                'level': 'INFO',
                'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                'file': 'survey_analyzer.log',
                'max_bytes': 10485760,  # 10MB
                'backup_count': 5
            },
            'data_validation': {
                'min_samples': 10,
                'max_missing_ratio': 0.5,
                'min_numeric_features': 1
            },
            'data_cleaning': {
                'remove_duplicates': False,
                'clean_column_names': True,
                'missing_value_strategy': 'auto',
                'outlier_strategy': 'none',
                'auto_convert_types': True,
                'clean_text': True
            }
        }
    
    def _load_config_file(self) -> None:
        """从配置文件加载配置"""
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    file_config = json.load(f)
                self._merge_config(file_config)
            except (json.JSONDecodeError, IOError) as e:
                print(f"警告: 配置文件加载失败 {e}，使用默认配置")
    
    def _load_env_config(self) -> None:
        """从环境变量加载配置"""
        env_mappings = {
            'SURVEY_OUTPUT_DIR': ['output', 'base_dir'],
            'SURVEY_LOG_LEVEL': ['logging', 'level'],
            'SURVEY_DEFAULT_CLUSTERS': ['analysis', 'default_clusters'],
            'SURVEY_RANDOM_STATE': ['analysis', 'random_state']
        }
        
        for env_var, config_path in env_mappings.items():
            value = os.getenv(env_var)
            if value:
                self._set_nested_config(config_path, value)
    
    def _merge_config(self, new_config: Dict[str, Any]) -> None:
        """合并配置"""
        def merge_dict(base: Dict, update: Dict) -> Dict:
            for key, value in update.items():
                if key in base and isinstance(base[key], dict) and isinstance(value, dict):
                    merge_dict(base[key], value)
                else:
                    base[key] = value
            return base
        
        merge_dict(self._config, new_config)
    
    def _set_nested_config(self, path: list, value: Any) -> None:
        """设置嵌套配置值"""
        config = self._config
        for key in path[:-1]:
            if key not in config:
                config[key] = {}
            config = config[key]
        
        # 类型转换
        if path[-1] in ['default_clusters', 'random_state']:
            value = int(value)
        elif path[-1] in ['max_missing_ratio', 'outlier_threshold']:
            value = float(value)
        
        config[path[-1]] = value
    
    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值"""
        keys = key.split('.')
        config = self._config
        
        for k in keys:
            if isinstance(config, dict) and k in config:
                config = config[k]
            else:
                return default
        
        return config
    
    def set(self, key: str, value: Any) -> None:
        """设置配置值"""
        keys = key.split('.')
        config = self._config
        
        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]
        
        config[keys[-1]] = value
    
    def save(self, file_path: Optional[str] = None) -> None:
        """保存配置到文件"""
        save_path = file_path or self.config_file
        os.makedirs(os.path.dirname(save_path), exist_ok=True)
        
        with open(save_path, 'w', encoding='utf-8') as f:
            json.dump(self._config, f, ensure_ascii=False, indent=2)
    
    @property
    def output_dirs(self) -> Dict[str, str]:
        """获取输出目录配置"""
        base_dir = self.get('output.base_dir')
        return {
            'base': base_dir,
            'charts': os.path.join(base_dir, self.get('output.charts_dir')),
            'reports': os.path.join(base_dir, self.get('output.reports_dir')),
            'data': os.path.join(base_dir, self.get('output.data_dir'))
        }
    
    def __getitem__(self, key: str) -> Any:
        """支持字典式访问"""
        return self.get(key)
    
    def __setitem__(self, key: str, value: Any) -> None:
        """支持字典式设置"""
        self.set(key, value)